#pragma once

#include <string>
#include <list>
#include <map>
#include <mythread.hxx>
#include <mymutex.hxx>

using namespace std;

class SHTunel;
class FileLog;
class TaskManager;

class SHTunelManager
{
public:
	/******************************************************
	** typedefs
	*******************************************************/
	class SHTunelListUnit : public Thread
	{
	public:
		typedef list<SHTunel*> SHTunelList;
		SHTunelListUnit(const string& host, const string& method, SHTunelManager* manager=NULL, int size=20, int interval=20, FileLog* filelog=NULL);

		string Signature(void) const;
		
		static string Signature(const string& host, const string& method);

		void KeepAlives(void);
		SHTunel* GetSHTunel(void);

		void Shutdown(void);

	protected:
		virtual void Execute(Thread::Arg);
	private:
		string host;
		string method;
		int size;
		int keepInterval;
		time_t birth;
		int closed;
		SHTunelList shtunelList;
		SHTunelList::iterator iterSHTunelList;
		Mutex shtunelListInUse;
		SHTunelManager* manager;
		bool isShutdownRequested;
		FileLog* _filelog;
	};
	typedef map<string, SHTunelListUnit*> SHTnuelContainer;

	/******************************************************
	** ctor
	*******************************************************/
	SHTunelManager(TaskManager* taskManager, FileLog* filelog);
	~SHTunelManager();

	void Register(const string& host, const string& method, int size, int interval);

	SHTunel* GetSHTunel(const string& host, const string& method);
	void ReturnSHTunel(SHTunel* shtunel);

	void DisplayMsg(string msg, int level);

private:
	void Cleanup(void);

	SHTnuelContainer shtunelContainer;
	Mutex shtunelContainerInUse;
	
	TaskManager* taskManager;
	FileLog* _filelog;
};